use async_graphql::{Context, InputObject, Object, SimpleObject, Result};
use sea_orm::DatabaseConnection;
use crate::handler::order_handler::{cancel_order, confirm_receipt, create_order, get_order_by_id, get_orders, mark_as_delivered, pay_order};
use crate::utility::jwt::UserInfo;
use crate::graphql::AuthGuard;

// 添加连接类型用于游标分页
#[derive(SimpleObject)]
pub struct OrderConnection {
    pub orders: Vec<OrderObject>,
    pub has_next: bool,
    pub next_cursor: Option<u64>,
}

#[derive(Debug, Clone, SimpleObject)]
pub struct OrderProductObject {
    pub id: String,
    pub create_time: String,
    pub update_time: String,
    pub order_id: String,
    pub product_id: String,
    pub title: String,
    pub cover_addr: String,
    pub quantity: u32,
}

#[derive(Debug, Clone, SimpleObject)]
pub struct OrderObject {
    pub id: String,
    pub create_time: String,
    pub update_time: String,
    pub user_id: String,
    pub total_price: String,
    pub real_price: String,
    pub receiver_address: String,
    pub receiver_name: String,
    pub receiver_phone: String,
    pub pay_type: Option<String>,
    pub pay_time: Option<String>,
    pub status: String,
    pub products: Vec<OrderProductObject>,
}

// 添加游标分页输入对象
#[derive(InputObject)]
pub struct OrderPaginationInput {
    pub limit: u64,
    pub cursor: Option<u64>,
    pub status: Option<String>,
}

// 订单商品输入对象
#[derive(InputObject)]
pub struct OrderProductInput {
    pub product_id: String,
    pub quantity: u32,
}

// 创建订单输入对象
#[derive(InputObject)]
pub struct CreateOrderInput {
    pub receiver_address: String,
    pub receiver_name: String,
    pub receiver_phone: String,
    pub products: Vec<OrderProductInput>,
}



#[derive(Default)]
pub struct OrderQuery;

#[Object]
impl OrderQuery {

    /// 查询用户订单列表
    #[graphql(guard = "AuthGuard(\"order:select\")")]
    async fn user_orders(
        &self,
        ctx: &Context<'_>,
        user_id: u64,
        pagination: OrderPaginationInput,
    ) -> Result<OrderConnection> {
        let db = ctx.data::<DatabaseConnection>()?;
        get_orders(db, user_id, pagination.limit, pagination.cursor, pagination.status).await
    }

    /// 查询当前用户订单列表
    #[graphql(guard = "AuthGuard(\"\")")]
    async fn my_orders(
        &self,
        ctx: &Context<'_>,
        pagination: OrderPaginationInput,
    ) -> Result<OrderConnection> {

        let user_info = ctx.data::<UserInfo>()?;
        let db = ctx.data::<DatabaseConnection>()?;
        get_orders(db, user_info.user_id, pagination.limit, pagination.cursor, pagination.status).await
    }

    /// 根据订单ID查询订单详情（管理员权限）
    #[graphql(guard = "AuthGuard(\"order:select_by_id\")")]
    async fn order_by_id(
        &self,
        ctx: &Context<'_>,
        order_id: u64,
    ) -> Result<OrderObject> {
        let db = ctx.data::<DatabaseConnection>()?;
        get_order_by_id(db, order_id, None).await
    }

    /// 根据订单ID查询当前用户的订单详情
    #[graphql(guard = "AuthGuard(\"\")")]
    async fn my_order_by_id(
        &self,
        ctx: &Context<'_>,
        order_id: u64,
    ) -> Result<OrderObject> {
        let user_info = ctx.data::<UserInfo>()?;
        let db = ctx.data::<DatabaseConnection>()?;
        get_order_by_id(db, order_id, Some(user_info.user_id)).await
    }

}

// 添加OrderMutation结构体
#[derive(Default)]
pub struct OrderMutation;

#[Object]
impl OrderMutation {
    /// 创建订单（管理员权限）
    #[graphql(guard = "AuthGuard(\"order:create\")")]
    async fn create_order(
        &self,
        ctx: &Context<'_>,
        user_id: u64,
        input: CreateOrderInput,
    ) -> Result<OrderObject> {
        let db = ctx.data::<DatabaseConnection>()?;
        create_order(db, user_id, input).await
    }

    /// 当前用户创建订单
    #[graphql(guard = "AuthGuard(\"\")")]
    async fn create_my_order(
        &self,
        ctx: &Context<'_>,
        input: CreateOrderInput,
    ) -> Result<OrderObject> {
        let user_info = ctx.data::<UserInfo>()?;
        let db = ctx.data::<DatabaseConnection>()?;
        create_order(db, user_info.user_id, input).await
    }

    /// 支付订单
    #[graphql(guard = "AuthGuard(\"\")")]
    async fn pay_order(
        &self,
        ctx: &Context<'_>,
        order_id: String,
        pay_password: String,
    ) -> Result<OrderObject> {
        let user_info = ctx.data::<UserInfo>()?;
        let db = ctx.data::<DatabaseConnection>()?;
        pay_order(db, order_id, user_info.user_id, pay_password).await
    }

    /// 确认收货
    #[graphql(guard = "AuthGuard(\"\")")]
    async fn confirm_receipt(
        &self,
        ctx: &Context<'_>,
        order_id: String,
    ) -> Result<OrderObject> {
        let user_info = ctx.data::<UserInfo>()?;
        let db = ctx.data::<DatabaseConnection>()?;
        confirm_receipt(db, order_id, user_info.user_id).await
    }


    /// 标记订单为已送达
    #[graphql(guard = "AuthGuard(\"\")")]
    async fn mark_as_delivered(
        &self,
        ctx: &Context<'_>,
        order_id: String,
    ) -> Result<OrderObject> {
        let user_info = ctx.data::<UserInfo>()?;
        let db = ctx.data::<DatabaseConnection>()?;
        mark_as_delivered(db, order_id, user_info.user_id).await
    }

    /// 取消订单
    #[graphql(guard = "AuthGuard(\"\")")]
    async fn cancel_order(
        &self,
        ctx: &Context<'_>,
        order_id: String,
    ) -> Result<OrderObject> {
        let user_info = ctx.data::<UserInfo>()?;
        let db = ctx.data::<DatabaseConnection>()?;
        cancel_order(db, order_id, user_info.user_id).await
    }
}